#Redistricting Competition Replication R Code

# Dr. Matthew Nelson

#Read Data

data<-read.csv(file.choose())

#Install Packages

install.packages("dplyr")
install.packages("stringr")
install.packages("sandwich")
install.packages("lmtest")
install.packages("broom")
install.packages("huxtable")
install.packages("ggplot2")
install.packages("questionr")


#Load Packages

library(dplyr)
library(stringr)
library(sandwich)
library(lmtest)
library(broom)
library(huxtable)
library(ggplot2)
library(questionr)


### Table 1: Data Used in Redistricting Research

# Add Information

hux2<-huxtable(rbind(c("Research","Elections Analyzed","Years")
                     ,c("Abramowitz et al 2006", "US House","1980,1982,1990,1992,2000,2002")
                     ,c("Carson et al 2014", "US House","1972,1982,1992,2002,2012")
                     ,c("Forgette et al 2009", "State Legislature","1992,2002")
                     ,c("Henderson et al 2018", "US House and State Legislature","2010")
                     ,c("Lindgren and Southwell 2013", "US House","2002-2010")
                     ,c("Masket et al 2012", "State Legislature","2000-2008")
                     ,c("McDonald 2006", "US House","1990,1992")
                     ))

# Edit Table Dimensions

position(hux2)<-"left"

font_size(hux2)<-12

hux2<- set_all_borders(hux2, 0.6)

#View Table

hux2



### Figure 1: Percent of Independent Commission-Drawn Districts


#Percent Independent Commission per decade

twenty12s<- data %>% filter(year==2018|year==2016|year==2014|year==2012)
sum(twenty12s$indep_comm_rd)/ nrow(twenty12s)


twenty02s<- data %>% filter(year==2010|year==2008|year==2004|year==2002)
sum(twenty02s$indep_comm_rd)/ nrow(twenty02s)


twenty92s<- data %>% filter(year==2000|year==1998|year==1994|year==1992)
sum(twenty92s$indep_comm_rd)/ nrow(twenty92s)

twenty82s<- data %>% filter(year==1990|year==1988|year==1984|year==1982)
sum(twenty82s$indep_comm_rd)/ nrow(twenty82s)

# Add Graph Data

linedata<- data.frame(Cycle= c("1982-1990","1992-2000","2002-2010","2012-2018"),Percent=c(0.5, 2,4,17))

# Add Graph Details

linegraph<-ggplot(data=linedata, aes(x=Cycle, y=Percent, group=1)) + geom_line()+ geom_point() + scale_y_continuous(breaks=seq(0,18, by= 1)) + labs(y="% of Independent Commission-Drawn Districts", x="")

# View Graph

linegraph


### Figure 2: 2018 Redistricting Institutions

# Number of Redistricting Institutions in 2018

data4<-data %>% filter(year==2018)

nrow(data4)
sum(data4$indep_comm_rd)
sum(data4$poli_comm_rd)
sum(data4$court_rd)
sum(data4$Leg)

# Add Graph Data

graphics<-data.frame(number=c(154,38,74,162),names = c("Court","Political Commission", "Independent Commission", "Legislature"))

#Add Graph Details

p<-ggplot(data=graphics, aes(x=names, y=number)) +
  geom_bar(stat="identity") + xlab("") + ylab("Number of Districts") 

#View Graph

p

# Regression Models

#Incumbent Win Regression Model

# Create regression with control variables

incpwin2<-glm(incpwin~indep_comm_rd +poli_comm_rd+ court_rd  
              + south + open + qc + spend + dispar
              +  factor(data$year)+ factor(data$state), data=data, 
              family = "binomial")

# Calculate State Clustered Standard Errors

tidyinc2<-tidy(coeftest(incpwin2, vcov= vcovHC, cluster = ~ state))

# View Results

tidyinc2


#Semi-Competitive Regression Model

#Create regression with control variables

semicomp2<-glm(semicomp~indep_comm_rd +poli_comm_rd+ court_rd  
               + south + open + qc + spend + dispar
               +  factor(data$year)+ factor(data$state), data=data, 
               family = "binomial")

# Calculate Clustered Standard Errors

tidysemi2<-tidy(coeftest(semicomp2, vcov= vcovHC, cluster = ~ state))

#View Results

tidysemi2

#Competitive Regression Model



#Create regression with control variables
comp2<-glm(comp~indep_comm_rd +poli_comm_rd+ court_rd 
           + south + open + qc + spend + dispar
           +  factor(data$year)+ factor(data$state), data=data, 
           family = "binomial")

# Calculate Clustered Standard Errors

tidycomp2<-tidy(coeftest(comp2, vcov= vcovHC, cluster = ~ state))

#View Results

tidycomp2


### Table 2 : Regression Models


#Regression Table 

# Add regression results to table (ignore formatting warning message)

table3<-huxreg('Incumbent Party Win'= tidyinc2, 'Semi-Competitive'= tidysemi2, 'Competitive'= tidycomp2)

# Remove rows showing each state's fixed effect

table3<-table3[-c(20:141),]

# Add row with regression info

table3<-rbind(table3, c("State & Year Fixed Effects", "Yes", "Yes", "Yes"), c("State Clustered Standard Errors", "Yes", "Yes", "Yes"), c("N", "6872", "6979", "6979"), c("AIC", "2424", "4248", "3788"), c( "*** p < 0.001;  ** p < 0.01;  * p < 0.05.","","",""))

#Rename Rows

table3[4,1]<- "Independent Commission"

table3[6,1]<- "Political Commission"

table3[8,1]<- "Court"

table3[10,1]<-"South"

table3[12,1]<-"Open Seat"

table3[14,1]<-"Quality Challenger"

table3[16,1]<-"Spending"

table3[18,1]<- "Partisanship"

# Edit Table Formatting

number_format(table3)[22:23,2:4]<-NA
bold(table3)[1, ]   <- TRUE
bottom_border(table3)[23, ] <- 1
position(table3)<-"left"

#View Table

table3

### Table 3:  Odds Ratio Conversion (relative to legislative redistricting)


#Odds Ratio Conversion

exp(c(-0.731,-0.821,-0.108))

exp(c(1.101,-0.193, 0.187))

exp(c(0.813,0.429,0.410))

# Add information to table

table2 <- hux('Redistricting Type'    = c('Independent Commission', 'Political Commission', 'Court'), 
              "Incumbent Party Win"       = c("0.48*", "0.44", "0.90"),
              "Semi-Competitive"      = c("3.01***" ,"0.82", "1.21"),
              "Competitive"      = c("2.25**", "1.54", "1.51***"),add_colnames = TRUE )

#Edit Table Dimensions

bold(table2)[1, ]   <- TRUE
bottom_border(table2)[1, ] <- 1
position(table2)<- "left"

#View Table

table2

### Figure 3: Odds Ratio for Competitive Elections with Confidence Intervals

#Calculate Odds Ratio with confidence interval

odds.ratio(comp2, level= 0.95 )

# Odds Ratio, 2.5%, 97.5%

#IRC: 2.3 , 1.3 , 3.9

#PC: 1.5,  0.8 , 2.9

#Court: 1.5, 1.2, 1.9

# Add data to graph

graphdata<-data.frame( name=c ("Independent Commission", "Political Commission", "Court"),
                       value= c(2.3, 1.5, 1.5), minsd= c(1.3,0.8, 1.2), maxsd= c(3.9 , 2.9, 1.9) )

# Edit graph details

p2<-ggplot(graphdata)  +
  geom_pointrange( aes(x=name, y=value, ymin=minsd, ymax=maxsd), colour="black", alpha=0.9, size=1.3) +
  geom_errorbar( aes(x=name, ymin=minsd, ymax=maxsd), width=0.4, colour="black", alpha=0.9, size=1.3) +
  labs(y= "Odds compared to Legislature", x= "" )

#View Graph

p2

# Appendix Regression Robustness Checks

### Appendix

#Table A1 : No Control Variables

#Incumbent Win 
incpwin3<-glm(incpwin~indep_comm_rd +poli_comm_rd+ court_rd  , data=data, family = "binomial")


#Semi-Competitive Races
semicomp3<-glm(semicomp~indep_comm_rd +poli_comm_rd+ court_rd  , data=data,family = "binomial")


#Competitive Races
comp3<-glm(comp~indep_comm_rd +poli_comm_rd+ court_rd , data=data,family = "binomial")


#Regression Table

table4<-huxreg('Incumbent Party Win'= incpwin3, 'Semi-Competitive'= semicomp3, 'Competitive'= comp3)
table4<-table4[-c(11),]

table4[4,1]<- "Independent Commission"

table4[6,1]<- "Political Commission"

table4[8,1]<- "Court"

bold(table4)[1, ]   <- TRUE
position(table4)<-"left"

table4

#Table A2: Different Specifications for Competition

comp5<-glm(comp5~indep_comm_rd +poli_comm_rd+ court_rd  + factor(data$year)+ factor(data$state), data=data,family = "binomial")
tidycomp5<-tidy(coeftest(comp5, vcov= vcovHC, cluster = ~ state))

comp6<-glm(comp6~indep_comm_rd +poli_comm_rd+ court_rd  + factor(data$year)+ factor(data$state), data=data,family = "binomial")
tidycomp6<-tidy(coeftest(comp6, vcov= vcovHC, cluster = ~ state))

#Regression Table

table6<-huxreg(  'Between 44 and 56'=tidycomp5, 'Between 43 and 57'=tidycomp6)

table6<-table6[-c(10:133),]

table6[4,1]<- "Independent Commission"

table6[6,1]<- "Political Commission"

table6[8,1]<- "Court"

table6<-rbind(table6, c("State & Year Fixed Effects", "Yes","Yes"), c("State Clustered Standard Errors", "Yes", "Yes"), c( "N  ","8136", " 8136 "), c("AIC","6678", "7365"), c( "*** p < 0.001;  ** p < 0.01;  * p < 0.05.","",""))

number_format(table6)[12:14,2:3]<-NA

bottom_border(table6)[13, ] <- 1
bold(table6)[1, ]   <- TRUE
position(table6)<-"left"


table6



#Table A3: Without Uncontested/ Same Party


comp4<-glm(comp4~indep_comm_rd +poli_comm_rd+ court_rd  + factor(data$year)+ factor(data$state), data=data,family = "binomial")
tidycomp4<-tidy(coeftest(comp4, vcov= vcovHC, cluster = ~ state))


# Regression Table

table5<-huxreg(  'Competitive'=tidycomp4)

table5<-table5[-c(10:133),]

table5[4,1]<- "Independent Commission"

table5[6,1]<- "Political Commission"

table5[8,1]<- "Court"

table5<-rbind(table5, c("State & Year Fixed Effects", "Yes"), c("State Clustered Standard Errors", "Yes"), c( "N", "6979"), c("AIC","5664"), c( "*** p < 0.001;  ** p < 0.01;  * p < 0.05.",""))

number_format(table5)[12:13,2]<-NA

bottom_border(table5)[13, ] <- 1
bold(table5)[1, ]   <- TRUE
position(table5)<-"left"

table5


# Table A4: Change Years

data2<- data %>% filter(year==2018|year==2016|year==2014|year==2012|year==2010|year==2008|year==2006|year==2004|year==2002)


#Incumbent Win 
incpwin7<-glm(incpwin~indep_comm_rd +poli_comm_rd+ court_rd  + factor(data2$year)+ factor(data2$state), data=data2, family = "binomial")
coeftest(incpwin7, vcov= vcovHC, cluster = ~ state)
tidyinc7<-tidy(coeftest(incpwin7, vcov= vcovHC, cluster = ~ state))

#Semi-Competitive Races
semicomp7<-glm(semicomp~indep_comm_rd +poli_comm_rd+ court_rd  + factor(data2$year)+ factor(data2$state), data=data2,family = "binomial")
coeftest(semicomp7, vcov= vcovHC, cluster = ~ state)
tidysemi7<-tidy(coeftest(semicomp7, vcov= vcovHC, cluster = ~ state))

#Competitive Races
comp7<-glm(comp~indep_comm_rd +poli_comm_rd+ court_rd  + factor(data2$year)+ factor(data2$state), data=data2,family = "binomial")
coeftest(comp7, vcov= vcovHC, cluster = ~ state)
tidycomp7<-tidy(coeftest(comp7, vcov= vcovHC, cluster = ~ state))

# Regression Table

table7<-huxreg('Incumbent Party Win'= tidyinc7, 'Semi-Competitive'= tidysemi7, 'Competitive'= tidycomp7)

table7<-table7[-c(10:111),]

table7<-rbind(table7, c("State & Year Fixed Effects", "Yes", "Yes", "Yes"), c("State Clustered Standard Errors", "Yes", "Yes", "Yes"),  c( "N  ","3800 ", "3852 ", "3852"), c("AIC","1769", "4205", "2666"), c( "*** p < 0.001;  ** p < 0.01;  * p < 0.05.","","",""))

table7[4,1]<- "Independent Commission"

table7[6,1]<- "Political Commission"

table7[8,1]<- "Court"

number_format(table7)[12:13,2:4]<-NA
bold(table7)[1, ]   <- TRUE
bottom_border(table7)[13, ] <- 1
position(table7)<-"left"

table7

#Table A5: Consider Quality Challenger as Dependent Variable


qualitychal<-glm(qc~indep_comm_rd +poli_comm_rd+ court_rd  + factor(data$year)+ factor(data$state), data=data, family = "binomial")
coeftest(qualitychal, vcov= vcovHC, cluster = ~ state)
tidyqc8<-tidy(coeftest(qualitychal, vcov= vcovHC, cluster = ~ state))

table8<-huxreg(  'Quality Challenger'=tidyqc8)

table8<-table8[-c(10:133),]

table8[4,1]<- "Independent Commission"

table8[6,1]<- "Political Commission"

table8[8,1]<- "Court"

table8<-rbind(table8, c("State & Year Fixed Effects", "Yes"), c("State Clustered Standard Errors", "Yes"),c("N","8107"),c("AIC","7383"),c( "*** p < 0.001;  ** p < 0.01;  * p < 0.05.",""))

number_format(table8)[12:13,2]<-NA
bottom_border(table8)[13, ] <- 1
bold(table8)[1, ]   <- TRUE
position(table8)<-"left"

table8

#Table A6:  Presidential Competition as Dependent Variable


binarypres5<-glm(binarypres~indep_comm_rd +poli_comm_rd+ court_rd  + factor(data$year)+ factor(data$state), data=data, family = "binomial")
coeftest(binarypres5, vcov= vcovHC, cluster = ~ state)
tidybp5<-tidy(coeftest(binarypres5, vcov= vcovHC, cluster = ~ state))

table13<-huxreg(  'Presidential Competition'=tidybp5)

table13<-table13[-c(10:133),]

table13[4,1]<- "Independent Commission"

table13[6,1]<- "Political Commission"

table13[8,1]<- "Court"

table13<-rbind(table13, c("State & Year Fixed Effects", "Yes"), c("State Clustered Standard Errors", "Yes"),c("N","8137"),c("AIC","9055"),c( "*** p < 0.001;  ** p < 0.01;  * p < 0.05.",""))

number_format(table13)[12:13,2]<-NA
bottom_border(table13)[13, ] <- 1
bold(table13)[1, ]   <- TRUE
position(table13)<-"left"

table13




